package day30.homework;

import java.io.*;

/**
 * 文件编码转换程序
 * 将GBK编码的文件转换为UTF-8编码
 * 
 * 该程序演示了如何使用Java IO流进行文件编码转换:
 * 1. 使用FileInputStream读取文件的字节数据
 * 2. 使用InputStreamReader将字节数据按照指定编码(GBK)转换为字符
 * 3. 使用BufferedReader提供缓冲功能，提高读取效率
 * 4. 使用FileOutputStream写入字节数据到新文件
 * 5. 使用OutputStreamWriter将字符按照指定编码(UTF-8)转换为字节
 * 6. 使用BufferedWriter提供缓冲功能，提高写入效率
 */
public class hw2 {
    /**
     * 程序主入口方法
     * 执行文件编码转换的主要逻辑
     * @param args 命令行参数数组
     */
    public static void main(String[] args) {
        // 定义源文件和目标文件路径
        // sourceFile: 原始文件路径，该文件应使用GBK编码保存
        // targetFile: 转换后文件的保存路径，该文件将使用UTF-8编码保存
        String sourceFile = "D:\\test\\File_GBK.txt";
        String targetFile = "D:\\test\\File_UTF8.txt";
        
        // 声明需要使用的流对象，初始化为null以便在finally块中进行资源释放检查
        // FileInputStream: 文件字节输入流，用于从文件中读取原始字节数据
        FileInputStream fis = null;
        // InputStreamReader: 字节流转字符流的桥梁，可指定字符编码进行转换
        InputStreamReader isr = null;
        // BufferedReader: 提供缓冲功能的字符输入流，提高读取效率，支持按行读取
        BufferedReader br = null;
        // FileOutputStream: 文件字节输出流，用于向文件中写入字节数据
        FileOutputStream fos = null;
        // OutputStreamWriter: 字符流转字节流的桥梁，可指定字符编码进行转换
        OutputStreamWriter osw = null;
        // BufferedWriter: 提供缓冲功能的字符输出流，提高写入效率，支持按行写入
        BufferedWriter bw = null;
        
        try {
            // 创建GBK编码的输入流链
            // FileInputStream: 从指定文件路径创建字节输入流，读取文件的原始字节数据
            fis = new FileInputStream(sourceFile);
            // InputStreamReader: 将字节流包装为字符流，并指定使用GBK编码进行解码
            // GBK编码是中国国家标准，支持中文字符的编码
            isr = new InputStreamReader(fis, "GBK");
            // BufferedReader: 为字符流添加缓冲功能，提高读取效率，支持readLine()方法
            br = new BufferedReader(isr);
            
            // 创建UTF-8编码的输出流链
            // FileOutputStream: 创建字节输出流，将字节数据写入到指定的目标文件中
            fos = new FileOutputStream(targetFile);
            // OutputStreamWriter: 将字符流包装为字节流，并指定使用UTF-8编码进行编码
            // UTF-8编码是国际通用的Unicode编码方式，支持全球各种语言字符
            osw = new OutputStreamWriter(fos, "UTF-8");
            // BufferedWriter: 为字符流添加缓冲功能，提高写入效率，支持newLine()方法
            bw = new BufferedWriter(osw);
            
            // 按行读取并写入，执行实际的编码转换过程
            // 声明一个字符串变量用于存储每次读取的一行内容
            String line;
            // 循环读取源文件的每一行内容，直到文件末尾返回null为止
            // readLine()方法一次读取一行文本，不包括行终止符，读到文件末尾时返回null
            while ((line = br.readLine()) != null) {
                // 将读取到的一行内容写入到目标文件中
                // write()方法将字符串内容写入到缓冲区中
                bw.write(line);
                // 写入一个行分隔符，根据运行系统不同可能是\n、\r或\r\n
                // newLine()方法确保在不同操作系统中都能正确换行
                bw.newLine();
            }
            
            // 文件转换完成，输出提示信息
            System.out.println("文件转换完成！");
            // 输出源文件信息，包括文件路径和编码格式
            System.out.println("源文件: " + sourceFile + " (GBK编码)");
            // 输出目标文件信息，包括文件路径和编码格式
            System.out.println("目标文件: " + targetFile + " (UTF-8编码)");
            
        // 捕获IO操作过程中可能发生的异常
        } catch (IOException e) {
            // 当文件转换过程中发生IO错误时，输出错误信息
            System.err.println("文件转换过程中发生错误: " + e.getMessage());
            // 打印详细的异常堆栈跟踪信息，便于调试和问题定位
            e.printStackTrace();
        } finally {
            // 手动关闭所有流，确保系统资源得到正确释放
            // 使用finally块确保无论是否发生异常都会执行资源释放操作
            try {
                // 按照后创建先关闭的原则，先关闭输出流再关闭输入流
                // 检查BufferedReader是否成功创建，如果创建了就关闭它
                if (br != null) br.close();
                // 检查InputStreamReader是否成功创建，如果创建了就关闭它
                if (isr != null) isr.close();
                // 检查FileInputStream是否成功创建，如果创建了就关闭它
                if (fis != null) fis.close();
                // 检查BufferedWriter是否成功创建，如果创建了就关闭它
                if (bw != null) bw.close();
                // 检查OutputStreamWriter是否成功创建，如果创建了就关闭它
                if (osw != null) osw.close();
                // 检查FileOutputStream是否成功创建，如果创建了就关闭它
                if (fos != null) fos.close();
            // 捕获在关闭流过程中可能发生的IO异常
            } catch (IOException e) {
                // 当关闭流时发生错误，输出错误信息
                System.err.println("关闭流时发生错误: " + e.getMessage());
                // 打印详细的异常堆栈跟踪信息，便于调试和问题定位
                e.printStackTrace();
            }
        }
    }
}